/* 
 * (C) 2013 Daniel Garcia <contacto {at} danigarcia.org>
 * 
 * http://danigarcia.org
 * 
 * This file is part of BlackList.
 * 
 * BlackList is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * BlackList is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with BlackList.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package org.danigarcia.android.blacklist.phone;

import org.danigarcia.android.blacklist.database.ConfigManager;
import org.danigarcia.android.blacklist.database.DataManager;
import org.danigarcia.android.blacklist.service.BlockingService;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;

public class SMSReceiver extends BroadcastReceiver {

	private static final String TAG = SMSReceiver.class.getName();
	public static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
	
	private DataManager dManager 		= null;
	
	/**
	 * Receives SMS incoming events and filters them
	 * @param dm DataManager to access to the internal application database
	 * @param blockFilteredSms If true, it will check the sms bodies, blocking those with a blocked number on it
	 * @param saveSms Save the filtered sms in the application database
	 */
	public SMSReceiver(DataManager dm)
	{
		this.dManager 	= dm;
		d(TAG, "SMSReceiver(): Receiver created");
	}
	
	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		String smsNumber = "";
		if(action.equals(SMS_RECEIVED))
		{
			boolean notification = false;
			
			//Toast.makeText(context, "SMS RECEIVED", Toast.LENGTH_LONG).show();
			d(TAG, "onReceive(): SMS_RECEIVED");
			
			String[] blockedNumbers = dManager.getAllBlockedNumbersAsArray();
			
			if(blockedNumbers == null)
			{
				d(TAG, "blockedNumbers IS NULL");
				return;
			}
			Bundle bundle = intent.getExtras();
			
			// Getting the sender number
			Object[] pdus = (Object[]) bundle.get("pdus");
			
			// Go through all pdus
			for(Object pdu : pdus)
			{
				d(TAG, "onReceive(): Entering outer FOR");
				// Extract message
				SmsMessage msg = SmsMessage.createFromPdu((byte[])pdu);
				smsNumber = msg.getOriginatingAddress();					// Number
				String sms = msg.getMessageBody();							// Message body
				
				// Go through all blocked numbers
				for(String phoneNumber : blockedNumbers)
				{
					d(TAG, "onReceive(): Inner for: " + phoneNumber);
					String blockedPhone = phoneNumber;

					if((phoneNumber.endsWith(smsNumber)) && (!phoneNumber.equals(smsNumber)))
					{
						blockedPhone = smsNumber;
					}
					
					d(TAG, String.format("onReceive(): blockedPhone: %s. phoneNumber: %s. smsNumber: %s. phoneNumber.endsWith(smsNumber)): %s)", blockedPhone, phoneNumber, smsNumber, phoneNumber.endsWith(smsNumber)));
					// If the sender sends a message, we block it and, if the flag
					// is active, the message is saved into the database
					if(blockedPhone.equals(smsNumber))
					{
						d(TAG, String.format("(1) blockedPhone [%s] == smsNumber [%s]", blockedPhone, smsNumber));
						if(ConfigManager.getBoolean(ConfigManager.KEY_SAVE_SMS))
							dManager.insertSms(phoneNumber, phoneNumber, sms);
						notification = true;
						abortBroadcast();
					}
					
					// If blockFilteredSms flag is turned on, we'll check if the phone number
					// is also present in the sms body. That behavior is explained to avoid
					// sms from ISPs who sends SMS noticing about a missed call.
					else if(ConfigManager.getBoolean(ConfigManager.KEY_FILTER_SMS_BODY))
					{
						if(sms.contains(blockedPhone))
						{
							d(TAG, String.format("(2) blockedPhone [%s] == smsNumber [%s]", blockedPhone, smsNumber));
							if(ConfigManager.getBoolean(ConfigManager.KEY_SAVE_SMS))
								dManager.insertSms(smsNumber, phoneNumber, sms);
							notification = true;
							abortBroadcast();
						}
					}
					else
						d(TAG, String.format("blockedPhone [%s] != smsNumber [%s]", blockedPhone, smsNumber));
				} // End inner for
			} // End outer for
			
			if(notification)
			{
				// Update notification
				if (context instanceof BlockingService) 
				{
					if (ConfigManager.getBoolean(ConfigManager.KEY_SHOW_NOTIFICATIONS))
						((BlockingService) context).updateNotification(smsNumber, false, true);
				}
			}
		}
	}

	private void d(String tag, String message)
	{
		if(ConfigManager.DEBUG_LOGGING)
			Log.d(tag, message);
	}
}
